﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

using com.vs.DataAccess;
using com.vs.DataAccess.DO;
using com.vs.General;

namespace com.vs.Inventory.BL
{
    public class LocationManager
    {
        private static LocationManager _mgr = null;

        public static LocationManager GetInstance()
        {
            if (_mgr == null)
                _mgr = new LocationManager();

            return _mgr;
        }

        public static bool DoseLocTrackLPN(Session sess, string stWarehouse, string stLocation)
        {
            DataTable dt = null;
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            string stTrack = null;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("WAREHOUSE", new KeyValuePair<string, object>("=", stWarehouse));
                dcCond.Add("LOCATION", new KeyValuePair<string, object>("=", stLocation));
                dt = LocationDO.GetTableByColumns(sess, DictionaryManager.ToList(dcCond), null);
                if (DataManager.IsEmpty(dt))
                    throw new Exception(MessageManager.MSG_LOC_001); //库位不存在

                stTrack = DataManager.GetString(dt.Rows[0], "TRACK_LPN");
                return StringManager.Equals(stTrack, "Y") ? true : false;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public string CreateLocations(Session sess, LocationDO fromLoc, LocationDO toLoc)
        {
            LocationDO locDO = null;

            try
            {
                locDO = fromLoc.Copy(sess) ;

                for (string f1 = fromLoc.TEMPLATE_FIELD1; isLessOrEqualThan(f1, toLoc.TEMPLATE_FIELD1); f1 = addByIncrease(f1, 1))
                {
                    locDO.LOCATION = null;
                    locDO.TEMPLATE_FIELD1 = f1;
                    locDO.TEMPLATE_FIELD2 = null;
                    locDO.TEMPLATE_FIELD3 = null;
                    locDO.TEMPLATE_FIELD4 = null;
                    locDO.TEMPLATE_FIELD5 = null;
                    for (string f2 = fromLoc.TEMPLATE_FIELD2; isLessOrEqualThan(f2, toLoc.TEMPLATE_FIELD2); f2 = addByIncrease(f2, 1))
                    {
                        locDO.TEMPLATE_FIELD2 = f2;
                        if (StringManager.IsEmpty(f2))
                        {
                            locDO.LOCATION = this.buildLocation(sess, locDO);
                            locDO.Insert(sess);
                            break;
                        }
                        for (string f3 = fromLoc.TEMPLATE_FIELD3; isLessOrEqualThan(f3, toLoc.TEMPLATE_FIELD3); f3 = addByIncrease(f3, 1))
                        {
                            locDO.TEMPLATE_FIELD3 = f3;
                            if (StringManager.IsEmpty(f3))
                            {
                                locDO.LOCATION = this.buildLocation(sess, locDO);
                                locDO.Insert(sess);
                                break;
                            }
                            for (string f4 = fromLoc.TEMPLATE_FIELD4; isLessOrEqualThan(f4, toLoc.TEMPLATE_FIELD4); f4 = addByIncrease(f4, 1))
                            {
                                locDO.TEMPLATE_FIELD4 = f4;
                                if (StringManager.IsEmpty(f4))
                                {
                                    locDO.LOCATION = this.buildLocation(sess, locDO);
                                    locDO.Insert(sess);
                                    break;
                                }
                                for (string f5 = fromLoc.TEMPLATE_FIELD5; isLessOrEqualThan(f5, toLoc.TEMPLATE_FIELD5); f5 = addByIncrease(f5, 1))
                                {
                                    locDO.TEMPLATE_FIELD5 = f5;
                                    locDO.LOCATION = this.buildLocation(sess, locDO);
                                    locDO.Insert(sess);
                                    if (StringManager.IsEmpty(f5))
                                        break;
                                }
                            }
                        }
                    }
                }

                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
            }
        }

        public string UpdateLocations(Session sess, LocationDO fromLoc, LocationDO toLoc)
        {
            LocationDO locDO = null;

            try
            {
                locDO = fromLoc.Copy(sess) ;

                for (string f1 = fromLoc.TEMPLATE_FIELD1; isLessOrEqualThan(f1, toLoc.TEMPLATE_FIELD1); f1 = addByIncrease(f1, 1))
                {
                    locDO.LOCATION = null;
                    locDO.TEMPLATE_FIELD1 = f1;
                    locDO.TEMPLATE_FIELD2 = null;
                    locDO.TEMPLATE_FIELD3 = null;
                    locDO.TEMPLATE_FIELD4 = null;
                    locDO.TEMPLATE_FIELD5 = null;
                    for (string f2 = fromLoc.TEMPLATE_FIELD2; isLessOrEqualThan(f2, toLoc.TEMPLATE_FIELD2); f2 = addByIncrease(f2, 1))
                    {
                        locDO.TEMPLATE_FIELD2 = f2;
                        if (StringManager.IsEmpty(f2))
                        {
                            locDO.LOCATION = this.buildLocation(sess, locDO);
                            locDO.Update(sess);
                            break;
                        }
                        for (string f3 = fromLoc.TEMPLATE_FIELD3; isLessOrEqualThan(f3, toLoc.TEMPLATE_FIELD3); f3 = addByIncrease(f3, 1))
                        {
                            locDO.TEMPLATE_FIELD3 = f3;
                            if (StringManager.IsEmpty(f3))
                            {
                                locDO.LOCATION = this.buildLocation(sess, locDO);
                                locDO.Update(sess);
                                break;
                            }
                            for (string f4 = fromLoc.TEMPLATE_FIELD4; isLessOrEqualThan(f4, toLoc.TEMPLATE_FIELD4); f4 = addByIncrease(f4, 1))
                            {
                                locDO.TEMPLATE_FIELD4 = f4;
                                if (StringManager.IsEmpty(f4))
                                {
                                    locDO.LOCATION = this.buildLocation(sess, locDO);
                                    locDO.Update(sess);
                                    break;
                                }
                                for (string f5 = fromLoc.TEMPLATE_FIELD5; isLessOrEqualThan(f5, toLoc.TEMPLATE_FIELD5); f5 = addByIncrease(f5, 1))
                                {
                                    locDO.TEMPLATE_FIELD5 = f5;
                                    locDO.LOCATION = this.buildLocation(sess, locDO);
                                    locDO.Update(sess);
                                    if (StringManager.IsEmpty(f5))
                                        break;
                                }
                            }
                        }
                    }
                }
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
            }
        }

        public string GetDefaultRecvDock(Session sess, string stWarehouse)
        {
            ConfigValueDO cvDO = null;

            cvDO = ConfigValueDO.GetModelByPK(sess, "RECEIVING", "DEFAULT_RECV_DOCK");
            if (cvDO == null)
                return null;
            else
                return cvDO.VALUE;
        }

        private bool isLessOrEqualThan(string s1, string s2)
        {
            if (StringManager.IsEmpty(s1) && StringManager.IsEmpty(s2))
                return true;

            if (s1.Length != s2.Length)
                return false;

            char[] arS1 = s1.ToCharArray();
            char[] arS2 = s2.ToCharArray();

            for (int i = 0; i < arS1.Length; i++)
            {
                if (arS1[i] < arS2[i])
                    return true;
                else if (arS1[i] == arS2[i])
                    continue;
                else
                    return false;
            }

            return true;
        }

        private string addByIncrease(string s1, int iStep)
        {
            char[] arS1 = s1.ToCharArray();

            for (int i = s1.Length - 1; i >= 0; i--)
            {
                if (arS1[i].Equals('Z'))
                    arS1[i] = 'A';
                else if (arS1[i].Equals('9'))
                    arS1[i] = '0';
                else
                {
                    arS1[i] = Convert.ToChar(Convert.ToInt32(arS1[i]) + 1);
                    break;
                }
            }

            return new string(arS1);
        }

        private string buildLocation(Session sess, LocationDO locDO)
        {
            string stLoc = "";
            if (!StringManager.IsEmpty(locDO.TEMPLATE_FIELD1))
                stLoc += locDO.TEMPLATE_FIELD1 + "-";
            if (!StringManager.IsEmpty(locDO.TEMPLATE_FIELD2))
                stLoc += locDO.TEMPLATE_FIELD2 + "-";
            if (!StringManager.IsEmpty(locDO.TEMPLATE_FIELD3))
                stLoc += locDO.TEMPLATE_FIELD3 + "-";
            if (!StringManager.IsEmpty(locDO.TEMPLATE_FIELD4))
                stLoc += locDO.TEMPLATE_FIELD4 + "-";
            if (!StringManager.IsEmpty(locDO.TEMPLATE_FIELD5))
                stLoc += locDO.TEMPLATE_FIELD5 + "-";

            return stLoc.Substring(0, stLoc.Length - 1);
        }
    }
}
